package com.fl.nj;

import com.fl.nj.config.DBConfig;
import com.fl.nj.pool.ConnectionPoolManager;
import com.fl.nj.rule.DataFetchRule;
import com.fl.nj.util.DBUtil;
import com.fl.nj.util.FileUtil;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 数据处理主类
 * 用于演示数据的获取、存储和处理流程
 */
public class DatabaseMigration {
    // 数据库连接池ID常量
    private static final String SOURCE_DB_POOL_ID = "source_db";
    private static final String TARGET_DB_POOL_ID = "target_db";
    // 数据文件路径
    private static final String DATA_FILE_PATH = "/tmp/migration_data.json";

    public static void main(String[] args) {
        try {
            // 1. 初始化源数据库连接池
            initSourceDatabase();
            // 2. 初始化目标数据库连接池
            initTargetDatabase();

            // 3. 根据配置的规则从源数据库获取数据
            List<Map<String, Object>> dataList = fetchDataFromSource();
            System.out.println("从源数据库获取数据成功，共" + dataList.size() + "条记录");

            // 4. 将数据保存到文件中
            saveDataToFile(dataList);
            System.out.println("数据已保存到文件：" + DATA_FILE_PATH);

            // 5. 从文件中读取数据
            List<Map<String, Object>> dataFromFile = readDataFromFile();
            System.out.println("从文件读取数据成功，共" + dataFromFile.size() + "条记录");

            // 6. 将数据写入目标数据库
            writeDataToTarget(dataFromFile);
            System.out.println("数据已成功写入目标数据库");

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭所有连接池
            ConnectionPoolManager.closeAllDataSources();
        }
    }

    /**
     * 初始化源数据库连接池
     */
    private static void initSourceDatabase() {
        DBConfig dbConfig = new DBConfig();
        dbConfig.setUrl("jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai");
        dbConfig.setUsername("root");
        dbConfig.setPassword("123456");
        dbConfig.setDriverClassName("com.mysql.cj.jdbc.Driver");
        ConnectionPoolManager.initDataSource(SOURCE_DB_POOL_ID, dbConfig);
    }

    /**
     * 初始化目标数据库连接池
     */
    private static void initTargetDatabase() {
        DBConfig dbConfig = new DBConfig();
        dbConfig.setUrl("jdbc:mysql://localhost:3306/test_target?useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai");
        dbConfig.setUsername("root");
        dbConfig.setPassword("123456");
        dbConfig.setDriverClassName("com.mysql.cj.jdbc.Driver");
        ConnectionPoolManager.initDataSource(TARGET_DB_POOL_ID, dbConfig);
    }

    /**
     * 根据规则获取数据
     * @return 数据列表
     * @throws SQLException 数据库操作异常
     */
    private static List<Map<String, Object>> fetchDataFromSource() throws SQLException {
        // 创建数据获取规则
        DataFetchRule rule = new DataFetchRule();
        rule.setTableName("user");
        rule.setWhereClause("status = 1");
        rule.setOrderBy("create_time DESC");
        rule.setLimit(1000); // 限制获取1000条记录

        // 根据规则从源数据库获取数据
        return DBUtil.fetchDataByRule(SOURCE_DB_POOL_ID, rule);
    }

    /**
     * 将数据保存到文件中
     * @param dataList 数据列表
     * @throws Exception 异常
     */
    private static void saveDataToFile(List<Map<String, Object>> dataList) throws Exception {
        FileUtil.saveDataToJsonFile(DATA_FILE_PATH, dataList);
    }

    /**
     * 从文件中读取数据
     * @return 数据列表
     * @throws Exception 异常
     */
    private static List<Map<String, Object>> readDataFromFile() throws Exception {
        return FileUtil.readDataFromJsonFile(DATA_FILE_PATH);
    }

    /**
     * 将数据写入数据库
     * @param dataList 数据列表
     * @throws SQLException 数据库操作异常
     */
    private static void writeDataToTarget(List<Map<String, Object>> dataList) throws SQLException {
        if (dataList.isEmpty()) {
            return;
        }

        // 获取表结构信息
        Map<String, Object> firstRow = dataList.get(0);
        List<String> columns = new ArrayList<>(firstRow.keySet());

        // 构建INSERT语句
        StringBuilder sqlBuilder = new StringBuilder();
        sqlBuilder.append("INSERT INTO target_user (");
        sqlBuilder.append(String.join(", ", columns));
        sqlBuilder.append(") VALUES (");
        sqlBuilder.append(String.join(", ", columns.stream().map(col -> "?").toArray(String[]::new)));
        sqlBuilder.append(")");

        String sql = sqlBuilder.toString();

        // 准备批量插入数据
        List<List<Object>> batchData = new ArrayList<>();
        for (Map<String, Object> row : dataList) {
            List<Object> rowData = new ArrayList<>();
            for (String column : columns) {
                rowData.add(row.get(column));
            }
            batchData.add(rowData);
        }

        // 执行批量插入
        int[] result = DBUtil.batchInsert(TARGET_DB_POOL_ID, sql, batchData);
        System.out.println("成功插入" + result.length + "条记录到目标数据库");
    }
}